# ============================================================
# * Copyright © hk. 2022-2025. All rights reserved.
# * File name: CMakeLists.txt
# * Author   : 苏木
# * Date     : 2025-05-22
# * Version  : 
# * Description: cmake version 3.16.3
# ============================================================
## https://cmake.com.cn/cmake/help/latest/guide/tutorial/index.html
## https://cmake.org/cmake/help/latest/

# 指定 CMake 的最低版本要求
# --------------------------------------------------
cmake_minimum_required(VERSION 3.10)


# 设置项目名称和使用的编程语言
# --------------------------------------------------
project(SPROJECT C)


# 指定可执行程序和源文件
# --------------------------------------------------
add_executable(app_demo.out main.c)

# Macro和function的区别
# --------------------------------------------------

# 3. 函数中调用宏
#    函数是独立作用域，只看到自己的参数；宏继承调用者的参数上下文(这里这个demo有疑问,后面搞明白再说)
message(STATUS "==> ${CMAKE_VERSION} 演示3: 函数中调用宏的演示1")
function(test_function arg)
	message(STATUS "[函数] 收到参数: ${arg}, ARGC: ${ARGC}, ARGV: ${ARGV}, ARGN: ${ARGN}")
endfunction()

macro(test_macro arg)
	message(STATUS "[宏] 收到参数: ${arg}, ARGC: ${ARGC}, ARGV: ${ARGV}, ARGN: ${ARGN}")
endmacro()

function(outer_func)
	message(STATUS "[outer_func] ARGC: ${ARGC}, ARGV: ${ARGV}, ARGN: ${ARGN}")
    test_function(A B C)  # 函数内部的 ARGN 只与本次调用相关
    test_macro(X Y Z)     # 新版本宏修改为真正的文本替换，按理说会看到 outer_func 的 ARGN！，也就是 P;Q;R
						  # 但是我使用了4.0.2和3.16.3,发现结果都是一样的，后续搞清楚了再说吧
endfunction()
outer_func(P Q R)
message(STATUS "")
# 输出如下：
# -- ==> 4.0.2 演示2: 参数作用域测试
# -- [outer_func] ARGC: 3, ARGV: P;Q;R, ARGN: P;Q;R
# -- [函数] 收到参数: A, ARGC: 3, ARGV: A;B;C, ARGN: B;C
# -- [宏] 收到参数: X, ARGC: 3, ARGV: X;Y;Z, ARGN: Y;Z

# -- ==> 3.16.3 演示2: 参数作用域测试
# -- [outer_func] ARGC: 3, ARGV: P;Q;R, ARGN: P;Q;R
# -- [函数] 收到参数: A, ARGC: 3, ARGV: A;B;C, ARGN: B;C
# -- [宏] 收到参数: X, ARGC: 3, ARGV: X;Y;Z, ARGN: Y;Z

message(STATUS "==> ${CMAKE_VERSION} 演示3: 函数中调用宏的演示2")
macro(bar)
    if (DEFINED ARGN)
        message(STATUS "    [macro]defined ARGN")
	else()
		message(STATUS "    [macro]not defined ARGN")
    endif()
    
    foreach(loop_var IN LISTS ARGN)
        message(STATUS "    [macro]loop_var: ${loop_var}")
    endforeach()
endmacro()
function(foo)
	message(STATUS "[函数 foo] ARGC: ${ARGC}, ARGV: ${ARGV}, ARGN: ${ARGN}")
    # 打印ARGV0参数值
    message(STATUS "  [函数 foo] ARGV0: ${ARGV0}")
    ## 调用宏
    bar(x y z)
endfunction()

foo(a b c)
message(STATUS "")
bar(x y z) ## 直接调用宏
message(STATUS "") 
# 输出如下：
# -- ==> 3.16.3 演示3: 函数中调用宏的演示2
# -- [函数 foo] ARGC: 3, ARGV: a;b;c, ARGN: a;b;c
# --   [函数 foo] ARGV0: a
# --     [macro]defined ARGN
# --     [macro]loop_var: a
# --     [macro]loop_var: b
# --     [macro]loop_var: c
# -- 
# --     [macro]not defined ARGN

# 在CMake语法中，函数会产生新的作用域，同时会默认生成新的变量即ARGN、ARGC、ARGV等等。
# 那么，在函数中调用宏时，仅仅只是把宏的实现语句往函数中拷贝了一份（即宏替换），所以，宏中语句的执行都基础函数变量的基础上。
# 所以，在宏中的打印并不是x y z，而是函数的参数 a b c
